﻿//-----------------------------------------------------------------------
// <copyright file="TextHandler.cs" company="None">
// None
// </copyright>
//-----------------------------------------------------------------------

namespace WCFDataServiceFormatExtensions
{
    using System;
    using System.Reflection;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Description;
    using System.ServiceModel.Dispatcher;
    using System.Text;
    using System.Xml;
    using System.IO;
    using System.Web.Configuration;
    using System.Diagnostics;
    using System.Xml.Linq;
    using System.Collections.Generic;
    //using WCFDataService.FormatExtensions;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class TextHandler
    {
        public static bool TextFormatRequestHandler(ref Message request, IClientChannel channel, InstanceContext instanceContext, out object token)
        {
            string requestType = "RequestType=TXT";


            char saparator = '|';
            string content = string.Empty;
            string hostName = string.Empty;
            string rootDir = string.Empty;


            bool success = false;
            HttpRequestMessageProperty httpmsg = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];
            UriTemplateMatch match = (UriTemplateMatch)request.Properties["UriTemplateMatchResults"];
            string format = match.QueryParameters["$format"];

            if (format != null && format.StartsWith("txt", StringComparison.InvariantCultureIgnoreCase))
            {
                ////check if saparator found 
                int saperatorPos = format.IndexOf('@');
                if (saperatorPos > 0)
                {
                    saparator = format.Substring(saperatorPos + 1).ToCharArray()[0];
                }

                string url = request.Properties.Via.AbsoluteUri;
                url = url.Substring(0, url.IndexOf("$format", StringComparison.InvariantCultureIgnoreCase));
                match.QueryParameters.Remove("$format");
                string corToken = string.Format("{0};saparator={1};URL={2}", requestType, saparator, url);
                token = corToken;
                success = true;
            }
            else
            {
                token = null;
            }

            return success;
        }

        public static bool TextFormatResponceHandler(ref Message reply, object correlationState)
        {
            string requestType = "RequestType=TXT";


            char saparator = '|';
            string content = string.Empty;
            string hostName = string.Empty;
            string rootDir = string.Empty;
            string downloadFolderName = "Downloads";
            bool success = false;
            HttpResponseMessageProperty response = reply.Properties[HttpResponseMessageProperty.Name] as HttpResponseMessageProperty;



            if (correlationState != null && correlationState is string)
            {
                Encoding encoding = ServerHelpers.GetReplyEncoding(response);
                success = true;
                bool isRequestTypeTXT = ((string)correlationState).ToLower().StartsWith(requestType.ToLower());

                char saparatorChar = ((string)correlationState).Split(';')[1].Split('=')[1].ToCharArray()[0];
                string url = ((string)correlationState).Split(';')[2];
                url = url.Substring(url.IndexOf('=') + 1);

                string versionFolder = string.Empty;
                string fileName = System.Guid.NewGuid() + ".txt";
                string downloadFileHTTPPath = string.Empty;

                rootDir = ServerHelpers.GetRootDir();
                string dropLocation = string.Empty;
                hostName = ServerHelpers.GetHostString(url);
                dropLocation = ServerHelpers.GetDropLocation(rootDir, downloadFolderName);
                downloadFileHTTPPath = string.Format("{0}/{1}", ServerHelpers.GetDownloadFolderHttpPath(hostName, downloadFolderName), fileName);


                if (response != null)
                {
                    string contentType = response.Headers["Content-Type"];
                    if (contentType != null)
                    {
                        if (isRequestTypeTXT && contentType.StartsWith("application/atom", StringComparison.InvariantCultureIgnoreCase))
                        {
                            response.Headers["Content-Type"] = "text/plain;charset=utf-8";
                            XmlDictionaryReader base64ReplyStream;



                            if (!Directory.Exists(dropLocation))
                            {
                                Directory.CreateDirectory(dropLocation);
                            }

                            string dropFileFullName = Path.Combine(dropLocation, fileName);
                            string pageHTML;

                            pageHTML = string.Format("<html><head> <title></title> </head> 	<body> <pre><a href=\"{0}\">Right click here to download</a> </pre>  </body> </html>", downloadFileHTTPPath);


                            try
                            {
                                //This is old code (ver 1.0) left just for reference
                                /*base64ReplyStream = reply.GetReaderAtBodyContents();

                                if (!AtomFeedConverter.ToTextFile(base64ReplyStream, encoding, saparator, dropFileFullName))
                                {
                                    content = "No Result Found";
                                }
                                else
                                {
                                    content = pageHTML;
                                }
                                 */

                                //New reader implementation ver 2.0
                                //It takes certificate if you want to export user certificate reffer to http://ashwini47-tts.blogspot.in/2012/02/how-to-export-loggedin-users.html
                                ODataReader reader = new ODataReader(url, null);
                                Exception ex = reader.SaveAsText(dropFileFullName, saparator);
                                if (ex != null)
                                {
                                    throw ex;
                                }
                                else if (reader.TotalDataRows > 0)
                                {
                                    pageHTML = string.Format("<html><head> <title></title> </head> 	<body> <a href=\"{0}\">Right click here to download</a> <p> RecordCount={1},Pages Count={2} Time Taken={3} ms</body> </html>", 
                                        downloadFileHTTPPath,reader.TotalDataRows,reader.TotalPages,
                                        (reader.EndTime-reader.StartTime).TotalMilliseconds);
                                   
                                    content = pageHTML;
                                }
                                else
                                {
                                    content = "No Result Found";
                                }
                            }
                            catch (Exception e)
                            {
                                pageHTML = e.Message + Environment.NewLine + e.StackTrace + Environment.NewLine + Environment.NewLine;
                                if (e.InnerException != null)
                                {
                                    pageHTML = pageHTML + e.InnerException.Message + Environment.NewLine + e.InnerException.StackTrace;
                                }

                                content = pageHTML;
                            }

                            Message newreply = Message.CreateMessage(MessageVersion.None, string.Empty, new CustomBinaryWriter(content, encoding));
                            newreply.Properties.CopyProperties(reply.Properties);

                            reply = newreply;
                        }
                    }
                }

            }
            return success;
        }
    }
}
